package org.jsola.hr.service.impl;

import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.FormGroupModuleCode;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IFormGroupFieldDAO;
import org.jsola.hr.dto.FormGroupFieldAddDTO;
import org.jsola.hr.dto.FormGroupFieldUpdateDTO;
import org.jsola.hr.entity.FormGroupFieldDO;
import org.jsola.hr.entity.FormGroupFieldValueDO;
import org.jsola.hr.query.FormGroupFieldQuery;
import org.jsola.hr.service.IFormGroupFieldService;
import org.jsola.hr.service.IFormGroupFieldValueService;
import org.jsola.hr.vo.FormGroupFieldListVO;
import org.jsola.hr.vo.FormGroupFieldVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 表单字段
 *
 * @author zhr
 */
@Service("hrFormGroupFieldServiceImpl")
public class FormGroupFieldServiceImpl implements IFormGroupFieldService {

    @Autowired
    private IFormGroupFieldDAO formGroupFieldDAO;

    @Autowired
    private IFormGroupFieldValueService formGroupFieldValueService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public FormGroupFieldVO save(FormGroupFieldAddDTO formGroupFieldAddDTO, TokenUser tokenUser) {
        // 转DO
        FormGroupFieldDO formGroupFieldDO = formGroupFieldAddDTO.to(FormGroupFieldDO.class);
        // 保存
        formGroupFieldDO = save(formGroupFieldDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return formGroupFieldDO.to(FormGroupFieldVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public List<FormGroupFieldVO> batchSave(List<FormGroupFieldAddDTO> formGroupFieldAddDTOList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(formGroupFieldAddDTOList)) {
            return null;
        }
        List<FormGroupFieldDO> formGroupFieldDOList = formGroupFieldAddDTOList
                .parallelStream()
                .map(formGroupFieldAddDTO -> {
                    FormGroupFieldDO formGroupFieldDO = formGroupFieldAddDTO.to(FormGroupFieldDO.class);
                    formGroupFieldDO.preInsert(tokenUser.getUserId());
                    formGroupFieldDO.setSiteId(tokenUser.getSiteId());
                    return formGroupFieldDO;
                }).collect(Collectors.toList());
        formGroupFieldDAO.insertListAndSetId(formGroupFieldDOList);
        return formGroupFieldDOList
                .parallelStream()
                .map(formGroupFieldDO -> formGroupFieldDO.to(FormGroupFieldVO.class))
                .collect(Collectors.toList());
    }

    @Override
    @Async
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void batchSaveDO(List<FormGroupFieldDO> insertList) {
        if (CollectionUtils.isEmpty(insertList)) {
            return;
        }
        formGroupFieldDAO.insertListAndSetId(insertList);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(FormGroupFieldUpdateDTO formGroupFieldUpdateDTO, TokenUser tokenUser) {
        //转DO
        FormGroupFieldDO formGroupFieldDO = formGroupFieldUpdateDTO.to(FormGroupFieldDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(formGroupFieldDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, Boolean check, Long... formGroupFieldIds) {
        if (!ObjectUtils.isEmpty(check) && check) {
            for (Long formGroupFieldId : formGroupFieldIds) {
                List<FormGroupFieldValueDO> fieldValueList = formGroupFieldValueService
                        .findByFieldId(formGroupFieldId, FormGroupModuleCode.DYCL);
                if(!CollectionUtils.isEmpty(fieldValueList)){
                    throw new ParamException("当前字段存在数据,不可删除");
                }
            }
        }
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) formGroupFieldIds);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds2(TokenUser tokenUser, Boolean check, Long... formGroupFieldIds) {
        if (!ObjectUtils.isEmpty(check) && check) {
            for (Long formGroupFieldId : formGroupFieldIds) {
                List<FormGroupFieldValueDO> fieldValueList = formGroupFieldValueService
                        .findByFieldId(formGroupFieldId, FormGroupModuleCode.DYCL);
                if(!CollectionUtils.isEmpty(fieldValueList)){
                    throw new ParamException("当前流程存在数据,不可删除");
                }
            }
        }
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) formGroupFieldIds);
    }

    @Override
    public FormGroupFieldVO selectById(Long formGroupFieldId, String siteId) {
        FormGroupFieldDO formGroupFieldDO = selectDOById(formGroupFieldId, siteId);
        if (formGroupFieldDO == null) {
            return null;
        }
        return formGroupFieldDO.to(FormGroupFieldVO.class);
    }

    @Override
    public List<FormGroupFieldListVO> select(FormGroupFieldQuery formGroupFieldQuery, String siteId) {
        List<FormGroupFieldDO> formGroupFieldDOList = selectDO(formGroupFieldQuery, siteId);
        if (CollectionUtils.isEmpty(formGroupFieldDOList)) {
            return formGroupFieldDOList == null ? null : new ArrayList<>();
        }
        return formGroupFieldDOList.stream()
                .map(formGroupFieldDO -> formGroupFieldDO.to(FormGroupFieldListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(FormGroupFieldQuery formGroupFieldQuery, String siteId) {
        Example example = buildExample(formGroupFieldQuery, siteId);
        return formGroupFieldDAO.selectCountByExample(example);
    }

    @Override
    public Page<FormGroupFieldListVO> selectPage(FormGroupFieldQuery formGroupFieldQuery, String siteId) {
        Example example = buildExample(formGroupFieldQuery, siteId);
        Page<FormGroupFieldDO> page = formGroupFieldDAO.selectPageByExample(example,
                formGroupFieldQuery.getPageNo(),
                formGroupFieldQuery.getPageSize());

        return page.to(FormGroupFieldListVO.class);
    }

    @Override
    public FormGroupFieldDO selectDOById(Long formGroupFieldId, String siteId) {
        return listById(formGroupFieldId, siteId);
    }

    @Override
    public List<FormGroupFieldDO> selectDO(FormGroupFieldQuery formGroupFieldQuery, String siteId) {
        Example example = buildExample(formGroupFieldQuery, siteId);
        return formGroupFieldDAO.selectByExample(example);
    }

    @Override
    public List<FormGroupFieldDO> selectBySubjectIdList(List<String> subjectIdList, String subjectType) {
        if (CollectionUtils.isEmpty(subjectIdList)) {
            return new ArrayList<>();
        }
        Example example = new Example(FormGroupFieldDO.class);
        example.and()
                .andIn("subjectId", subjectIdList)
                .andEqualTo("valid", true);
        if (!StringUtils.isEmpty(subjectType)) {
            example.and().andEqualTo("subjectType", subjectType);
        }
        example.orderBy("sort");
        return formGroupFieldDAO.selectByExample(example);
    }

    @Override
    public List<FormGroupFieldVO> selectFieldAddContentByQuery(FormGroupFieldQuery query, TokenUser tokenUser) {
        return formGroupFieldDAO.selectFieldAddContentByQuery(query, tokenUser.getSiteId());
    }

    /**
     * 根据查询参数，构建example
     *
     * @param formGroupFieldQuery 查询参数
     * @param siteId              所属站点id
     * @return example
     */
    private Example buildExample(FormGroupFieldQuery formGroupFieldQuery, String siteId) {
        Example example = new Example(FormGroupFieldDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        // 排序
        ExampleKit.setExampleOrder(example, formGroupFieldQuery.getOrders());
        return example;
    }
}




